/*
 *    Copyright 2014 Sam Y Ge
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */
package org.strx;

import java.util.Collections;
import java.util.Map;

/**
 * XML标签
 * 
 * @see Parser
 * 
 * @author <a href="mailto:samuel.y@foxmail.com">Sam Y Ge</a>
 */
abstract class Tag implements TagConst {
	/** 标签原始文本 */
	protected String tagStr;

	/** Tag类型 */
	protected TagType type;

	/** Tag名 */
	protected String name;

	/** 属性 */
	protected Map<String, String> attributes;

	/** 文本 */
	protected String text;

	/** 属性解析标记 */
	protected boolean attributesParsed;

	/** 文本解析标记 */
	protected boolean textParsed;

	/** 属性存在标记 */
	protected boolean hasAttr;

	/** 文本存在标记 */
	protected boolean hasText;

	/** 标签体 */
	protected String tagBody;

	/**
	 * <p>
	 * 简单Tag构造
	 * </p>
	 * 
	 * @param type
	 *            Tag的类型
	 * @param tagStr
	 *            Tag的原始标签文本
	 */
	protected Tag(TagType type, String tagStr) {
		this.type = type;
		this.tagStr = tagStr;
		this.attributes = Collections.emptyMap();

		// 标签名优先解析
		parseName();
	}

	/**
	 * 获取原始文本
	 * 
	 * @return 标签的原始文本
	 */
	final String getTagStr() {
		return tagStr;
	}

	/**
	 * 获取标签类型
	 * 
	 * @return 标签类型
	 */
	final TagType getType() {
		return type;
	}

	/**
	 * 获取标签名
	 * 
	 * @return 标签名
	 */
	final String getName() {
		return name;
	}

	/**
	 * 获取属性集合
	 * 
	 * @return 属性Map
	 */
	final Map<String, String> getAttributes() {
		if (!attributesParsed) {
			parseAttrs();
			attributesParsed = true;
		}

		return attributes;
	}

	/**
	 * 获取文本
	 * 
	 * @return 标签文本
	 */
	final String getText() {
		if (!textParsed) {
			parseText();
			textParsed = true;
		}

		return text;
	}

	/**
	 * 解析Tag名
	 */
	abstract void parseName();

	/**
	 * 解析Tag的属性
	 */
	abstract void parseAttrs();

	/**
	 * 解析Tag的文本
	 */
	abstract void parseText();

	/**
	 * {@inheritDoc}
	 */
	public String toString() {
		StringBuilder buff = new StringBuilder();
		buff.append("Tag[name=");
		buff.append(name);
		switch (type) {
		case START:
			buff.append(", type=START");
			break;
		case SELF_CLOSE:
			buff.append(", type=SELF_CLOSE");
			break;
		case END:
			buff.append(", type=END");
			break;
		case HEAD:
			buff.append(", type=HEAD");
			break;
		default:
			buff.append(", type=Unknow");
		}

		if (null != getAttributes()) {
			buff.append(", attributes=");
			buff.append(attributes);
		}
		if (null != getText()) {
			buff.append(", text=");
			buff.append(text);
		}
		buff.append("], TagStr=");
		buff.append(tagStr);

		return buff.toString();
	}

}
